package com.autumn.platform.dao.binding.handler.impl;

import java.lang.reflect.Method;

import org.apache.ibatis.session.SqlSession;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;

import com.autumn.platform.core.Utils;
import com.autumn.platform.dao.annotation.Merge;
import com.autumn.platform.dao.binding.handler.IMapperHandlerContext;

public class MergeMapperHandler extends AbstractTransactionMapperHandler  {

    public MergeMapperHandler() {
        super();
    }

    public MergeMapperHandler(int order) {
        super(order);
    }

    @Override
    public boolean supports(IMapperHandlerContext context) {
        return context.getMethod().isAnnotationPresent(Merge.class);
    }

    @Override
    public Object execute(SqlSession sqlSession, Object[] args, IMapperHandlerContext context) {
        final Object param = context.getParamResolver().getNamedParams(args);
        Method method = context.getMethod();
        Merge merge = method.getAnnotation(Merge.class);
        final String updateSqlRef = this.resolveSqlId(method, merge.updateSqlRef());
        final String insertSqlRef = this.resolveSqlId(method, merge.insertSqlRef());
        return this.executeWithTransaction(sqlSession, context, new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus status) {
            	int sqlCount = sqlSession.update(updateSqlRef, param);
            	if(0 == sqlCount) {
            		sqlCount = sqlSession.insert(insertSqlRef, param);
            	}
                return sqlCount;
            }
        });
    }

    /**
     * 解析SqlId
     * 
     * @param method
     * @param sqlRef
     * @return
     */
    private String resolveSqlId(Method method, String sqlRef) {
        if (Utils.isBlank(sqlRef)) {
            return method.getDeclaringClass().getName() + "." + method.getName();
        } else {
            return method.getDeclaringClass().getName() + "." + sqlRef;
        }
    }
}
